#include "RankSelectionStrategy.h"
#include "math.h"


RankSelectionStrategy::RankSelectionStrategy() : SelectionStrategy(),
                    currentIndex(0),
                    retCount(0)
{
    TRACE_FUNC
}

Chromosome* RankSelectionStrategy::selectOne(const QList<Chromosome*>& chromosomeList)
{
    TRACE_FUNC_ENTRY
	
    if(factorList.isEmpty())
        createTempList(chromosomeList.size());

    Chromosome* chromosome;

    chromosome = chromosomeList[currentIndex];
    ++retCount;

    qDebug() << "retCount: " << retCount;
    qDebug() << "currentIndex: " << currentIndex;
    qDebug() << "factorList.at(currentIndex): " << factorList.at(currentIndex);
		
    if(retCount >= factorList.at(currentIndex))
    {
        qDebug() << "change index";
        retCount = 0;
        ++currentIndex;
		
        if(currentIndex > chromosomeList.size()-1)
        {
            qDebug() << "change index currentIndex 0";
            currentIndex = 0;
        }
    }

    /*double randDistribution = static_cast<double>(qrand()) / static_cast<double>(RAND_MAX);

    //qDebug() << "randDistribution: " << randDistribution;

    QList<double>::iterator ind = qUpperBound(distributionList.begin(), distributionList.end(), randDistribution);

    int index = ind - distributionList.begin();*/

    TRACE_FUNC_EXIT
    return chromosome;//chromosomeList.value(index);
}

void RankSelectionStrategy::countDistribution()
{
    TRACE_FUNC_ENTRY
    double rankSum = 0;

    for(int i=0;i<factorList.size();++i)
        rankSum += factorList.at(i);

    double distributionSum = 0;

    //double averageGenerationFitness = rankSum/chromosomeList.size();
    //qDebug() << "rankSum: " << rankSum;
    //qDebug() << "averageGenerationFitness: " << averageGenerationFitness;

    for(int i=0;i<factorList.size();++i)
    {
        double rankProbability = factorList.at(i)/rankSum;
        double rankDistribution = distributionSum + rankProbability;
        distributionSum = rankDistribution;
        distributionList.append(rankDistribution);
       /* qDebug() << i << " fit: " << chromosomeList[i]->getFitness()
                << " chromProb: " << rankProbability
                << "chromDistrib: " << QString::number(rankDistribution, 'f', 10)
                << " expected: " << chromFit/averageGenerationFitness;*/
    }
    qDebug() << distributionList;

    TRACE_FUNC_EXIT
}

void RankSelectionStrategy::resetTempData()
{
    TRACE_FUNC_ENTRY
    currentIndex = 0;
    retCount = 0;
    factorList.clear();
    distributionList.clear();
    TRACE_FUNC_EXIT
}

void RankSelectionStrategy::createTempList(int listSize)
{
    //TODO check negative values!!!!!!!!!!
    //TODO count prob depend on rank and create roulette wheel
    for(int i=0;i<listSize;++i)
    {
        double value = -1*i + 10;
        factorList.append(value);
    }

    for(int i=0;i<factorList.size();++i)
        qDebug() << i << ": " << factorList.at(i);

    //countDistribution();
}
